#include "Hook.h"

#include <tlhelp32.h>
#include <tchar.h>


EXPORT_API PBYTE skip_jmp(PBYTE func){
    PBYTE pcode = func;
	if(pcode[0] == 0xe9){
		return skip_jmp(pcode + 5 + *(DWORD*)(pcode+1));
	} else if (pcode[0] == 0xeb) {
		return skip_jmp(pcode + 2 + *(CHAR *)(pcode+1));
	}
	return func;
}

EXPORT_API DWORD round_times(DWORD orig, DWORD times){
	return orig/times*times;
}

EXPORT_API PBYTE alloc_virtual_addr(const PBYTE addr) {
	SYSTEM_INFO sSysInfo =  {0};
	GetSystemInfo(&sSysInfo);
	const DWORD alloc_size = sSysInfo.dwAllocationGranularity;
	PBYTE base_addr = (PBYTE)round_times((DWORD)addr, alloc_size);
	PBYTE try_addr = base_addr;
	for(int i=0; (DWORD)try_addr<0x7FFF0000 && (DWORD)try_addr>0x00010000; i++){
		MEMORY_BASIC_INFORMATION base_info;
		DWORD ret = VirtualQuery(try_addr, &base_info, sizeof(base_info));
		if(ret == 0) {
			try_addr = NULL;
			break;
		}

		if(base_info.RegionSize >=  alloc_size){
			try_addr = (BYTE *)VirtualAlloc(try_addr, alloc_size, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE);
			if(try_addr) {
				break;
			}
		}

		try_addr = base_addr + alloc_size * (i%2*2 -1) * (i/2 + 1);
	}
	if((DWORD)try_addr >= 0x7FFF0000) try_addr = NULL;
	return try_addr;
}

